<?php

// 支付授权目录 112.124.44.172/wshop/
// 支付请求示例 index.php
// 支付回调URL http://112.124.44.172/wshop/?/Order/payment_callback
// 维权通知URL http://112.124.44.172/wshop/?/Service/safeguarding
// 告警通知URL http://112.124.44.172/wshop/?/Service/warning

/**
 * 订单类
 */
class Order extends Controller {

    public function __construct($ControllerName, $Action, $QueryString) {
        parent::__construct($ControllerName, $Action, $QueryString);
        $this->loadModel('Db');
    }

    // 支付回调页面
    public function payment_notify() {
        // postStr
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        // orderid 
        $orderId = $postObj->out_trade_no;
        // 微信交易单号
        $transaction_id = $postObj->transaction_id;
        // 更新订单状态
        $UpdateSQL = sprintf("UPDATE `orders` SET `wepay_serial` = '%s',`status` = 'payed',`bank_billno` = '%s' WHERE `order_id` = %s AND `status` <> 'payed';", $transaction_id, '', $orderId);
        $this->Db->query($UpdateSQL);
        // 邮件通知
        if ($orderId > 0) {
            $this->loadModel('User');
            $this->loadModel('mOrder');
            // 商户订单通知
            @$this->mOrder->OrderNotify($orderId);
            // 用户订单通知 模板消息
            @$this->mOrder->userNewOrderNotify($orderId, $postObj->OpenId);
            // 导入订单数据到个人信息
            @$this->User->importFromOrderAddress($orderId);
        }
        // 返回success
        echo "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    }

    // 订单确认页面
    public function cart() {
        global $config;
        $this->loadModel('User');
        // Unix时间戳
        $timestamp = time();
        // 随机字符串
        $nonceStr = rand(100000, 999999);
        if (Controller::inWechat() && $config->useWechatAddr) {
            $OauthURL = $this->root . $config->wxpayroot;
            $FinalURL = "http://" . $this->server('HTTP_HOST') . $this->server('REQUEST_URI');
            include_once(dirname(__FILE__) . "/../lib/Tools.php");
            $this->loadModel('WechatSdk');
            $AccessCode = WechatSdk::getAccessCode($OauthURL, "snsapi_base");
            if ($AccessCode !== FALSE) {
                // 获取到accesstoken和openid
                $AResult = WechatSdk::getAccessToken($AccessCode);
                #$openId = $AResult->openid;
                $AccessToken = $AResult->access_token;
            }
            // shareaddress
            $myaddr = new SignTool();
            $myaddr->setParameter("appid", APPID);
            $myaddr->setParameter("url", $FinalURL);
            $myaddr->setParameter("noncestr", $nonceStr);
            $myaddr->setParameter("timestamp", $timestamp);
            $myaddr->setParameter("accesstoken", $AccessToken);
            $addrsign = $myaddr->genSha1Sign();
            unset($AccessCode);
            // shareaddress
        }
        $this->loadModel('JsSdk');
        $signPackage = $this->JsSdk->GetSignPackage();
        // 收货地址接口Json包
        $addrsignPackage = array(
            "appId" => APPID,
            "scope" => "jsapi_address",
            "signType" => "sha1",
            "addrSign" => isset($addrsign) ? $addrsign : false,
            "timeStamp" => (string) $timestamp,
            "nonceStr" => (string) $nonceStr
        );
        $this->Smarty->assign('signPackage', $signPackage);
        $this->Smarty->assign('addrsignPackage', $this->toJson($addrsignPackage));
        $this->Smarty->assign('title', '购物车');
        $this->Smarty->assign('userInfo', (array) $this->User->getUserInfo());
        $this->show();
    }

    /**
     * Ajax生成订单
     */
    public function ajaxCreateOrder() {
        $this->loadModel('mOrder');
        $openid = $this->getOpenId();
        echo $this->mOrder->create($openid, '', json_decode($_POST['cartData'], true), $_POST['addrData'], $_POST['balancePay'] == 1, $_POST['yun'], $_POST['leword']);
    }

    protected function createNoncestr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str.= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
            //$str .= $chars[ mt_rand(0, strlen($chars) - 1) ];  
        }
        return $str;
    }

    /**
     * 格式化参数格式化成url参数
     */
    public function ToUrlParams($arr) {
        $buff = "";
        foreach ($arr as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 数组转换XML
     * @param type $arr
     * @return string
     */
    public function toXML($arr) {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml.="<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml.="<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    /**
     * Ajax获取订单请求数据包
     */
    public function ajaxGetBizPackage() {
        global $config;
        $orderId = intval($this->post('orderId'));
        $openid = $this->getOpenId();
        $totalFee = $this->countOrderSum($orderId) * 100;

        $nonceStr = $this->createNoncestr();

        $timeStamp = strval(time());

        $pack = array(
            'appid' => APPID,
            'body' => $config->shopName,
            'timeStamp' => $timeStamp,
            'mch_id' => PARTNER,
            'nonce_str' => $nonceStr,
            'notify_url' => "http://jc.esixu.com/payment_notify.php",
            'out_trade_no' => $orderId,
            'spbill_create_ip' => $this->getIp(),
            'total_fee' => $totalFee,
            'trade_type' => 'JSAPI',
            'openid' => $openid
        );

        $pack['sign'] = $this->paySign($pack);

        $xml = $this->toXML($pack);

        $ret = Curl::post('https://api.mch.weixin.qq.com/pay/unifiedorder', $xml);

        $postObj = json_decode(json_encode(simplexml_load_string($ret, 'SimpleXMLElement', LIBXML_NOCDATA)));

        $packJs = array(
            'appId' => APPID,
            'timeStamp' => $timeStamp,
            'nonceStr' => $nonceStr,
            'package' => "prepay_id=" . $postObj->prepay_id,
            'signType' => 'MD5'
        );

        $JsSign = $this->paySign($packJs);

        unset($packJs['timeStamp']);
        unset($packJs['appId']);

        $packJs['timestamp'] = $timeStamp;

        $packJs['paySign'] = $JsSign;

        $this->echoJson($packJs);
    }
    
    /**
     * 生成签名
     * @param type $pack
     * @return type
     */
    private function paySign($pack) {
        ksort($pack);

        $string = $this->ToUrlParams($pack);

        $string = $string . "&key=" . PARTNERKEY;

        $string = md5($string);

        $result = strtoupper($string);
        return $result;
    }

    /**
     * cookie
     * 计算订单总量
     * @return <float>
     */
    private function countOrderSum($orderid) {
        $sum = $this->Db->query("SELECT `order_amount` FROM `orders` WHERE `order_id` = $orderid;");
        return $sum[0]['order_amount'];
    }

    /**
     * expressDetail 查看物流情况
     */
    public function expressDetail($Query) {
        global $config;
        if (!isset($Query->order_id) && $Query->order_id > 0) {
            exit(0);
        }
        $Query->order_id = addslashes($Query->order_id);
        // 商品列表
        $orderProductsList = $this->Db->query("SELECT `catimg`,`pi`.product_name,`pi`.product_id,`sd`.product_count,`sd`.product_discount_price FROM `orders_detail` sd LEFT JOIN `products_info` pi on pi.product_id = sd.product_id WHERE `sd`.order_id = " . $Query->order_id);
        // 订单信息
        $orderData = $this->Db->getOneRow("SELECT * FROM `orders` WHERE `order_id` = $Query->order_id;");
        $expressCode = include dirname(__FILE__) . '/../config/express_code.php';

        $orderData['address'] = $this->Db->getOneRow("SELECT * FROM `orders_address` WHERE `order_id` = $Query->order_id;");
        $orderData['express_com1'] = $expressCode[$orderData['express_com']];
        $orderData['statusX'] = $config->orderStatus[$orderData['status']];
        $this->Smarty->assign('orderdetail', $orderData);
        $this->Smarty->assign('productlist', $orderProductsList);
        $this->Smarty->assign('title', '订单详情');
        $this->show();
    }

    /**
     * 订单取消
     * @todo a lot
     */
    public function cancelOrder() {
        $orderId = $_POST['orderId'];
        $cancelSql = "UPDATE " . TABLE_ORDERS . " SET `status` = 'canceled' WHERE `order_id` = $orderId;";
        $rst = $this->Db->query($cancelSql);
        # echo $cancelSql;
        echo $rst > 0 ? "1" : "0";
    }

    /**
     * 确认收货
     */
    public function confirmExpress($Query) {
        // orders >> received
        $this->loadModel('mOrder');
        $this->loadModel('WechatSdk');
        $orderId = intval($this->pPost('orderId'));
        if ($orderId > 0) {
            $updateSql = "UPDATE `orders` SET status = 'received',`receive_time` = NOW() WHERE `order_id` = $orderId;";
            // 推广结算
            $orderData = $this->mOrder->GetOrderDetail($orderId);
            $companyCom = $orderData['company_com'];
            if ($companyCom != '0' && $companyCom > 0) {
                // 代理商结算
                $clientId = $orderData['client_id'];
                $orderCount = $orderData['product_count'];
                // todo model
                foreach ($orderData['products'] as $productId => $count) {
                    $_rst = $this->Db->query("UPDATE `" . COMPANY_SPREAD . "` SET `turned` = `turned` + 1 WHERE `com_id` = '$companyCom' AND `product_id` = $productId;");
                    if (!$_rst) {
                        $this->Db->query("INSERT INTO `" . COMPANY_SPREAD . "` (`product_id`,`com_id`,`turned`) VALUES ($productId,'$companyCom',1);");
                    }
                }
                $companyInfo = $this->Dao->select()->from('companys')->where("id=$companyCom")->getOneRow();
                // 代理回报比例
                $percent = floatval($companyInfo['return_percent']);
                // 代理Openid
                $openid = $companyInfo['openid'];
                // 代理UID
                $comUid = $companyInfo['uid'];
                // 代理所获得收益
                $comAmount = floatval($orderData['order_amount'] * $percent);
                // 查询二级分销
                // 上级代理ID
                $comcom = $this->Dao->select('client_comid')->from('clients')->where("client_id=$comUid")->getOne();
                if ($comcom !== false) {
                    $comcomIncome = $comAmount * floatval($this->settings['com_sale_pcent']);
                    $comAmount = $comAmount - $comcomIncome;
                    // 二级回报
                    $this->Db->query("INSERT INTO `company_income_record` (`amount`,`date`,`client_id`,`order_id`,`com_id`,`pcount`) VALUE ($comcomIncome, NOW(), $clientId, $orderId, '$comcom',$orderCount);");
                }
                // 第一级回报
                $this->Db->query("INSERT INTO `company_income_record` (`amount`,`date`,`client_id`,`order_id`,`com_id`,`pcount`) VALUE ($comAmount, NOW(), $clientId, $orderId, '$companyCom',$orderCount);");
                Messager::sendText(WechatSdk::getServiceAccessToken(), $openid, date('Y-m-d') . " 您名下的会员总额为" . $orderData['order_amount'] . "的订单已完成，您获得 $comAmount 元收益！");
            }
            echo $this->Db->query($updateSql);
        } else {
            echo 0;
        }
    }

    /**
     * 订单发货
     */
    public function ExpressReady() {
        $this->loadModel('mOrder');
        $this->loadModel('WechatSdk');

        $orderId = intval($_POST['orderId']);
        $expressCode = $_POST['ExpressCode'];
        $expressCompany = $_POST['expressCompany'];

        if ($this->mOrder->despacthGood($orderId, $expressCode, $expressCompany)) {
            global $config;
            $this->loadModel('weiMiSms');
            $this->loadModel('Email');
            $this->loadModel('User');
            $expressList = include dirname(__FILE__) . '/../config/express_code.php';
            $orderData = $this->Db->getOneRow("SELECT `oa`.`order_id`,`oa`.`tel_number`,`od`.wepay_openid,`od`.client_id,`od`.serial_number,`od`.order_time,`oa`.user_name,`od`.order_amount FROM `orders` `od` LEFT JOIN `orders_address` `oa` ON `oa`.order_id = `od`.order_id WHERE `oa`.order_id = $orderId;");
            $userEmail = $this->User->getUserEmail($orderData['client_id']);
            $userInfo = $this->User->getUserInfo($orderData['client_id']);
            // sms notify
//            $this->weiMiSms->sendSmsTemplate($orderData['tel_number'], WEIMITEMPLATE1, array($expressList[$expressCompany], $expressCode));
            // email notify
            $subject = $this->settings['shopname'] . " - 订单发货通知 编号:" . $orderData['serial_number'];
            $orderInfo = array(
                'username' => $orderData['user_name'],
                'userphone' => $orderData['tel_number'],
                'time' => $orderData['order_time'],
                'amount' => $orderData['order_amount'],
                'list' => $this->Db->query("select pi.product_name as `name`,product_count as count from orders_detail od 
                left JOIN products_info pi on pi.product_id = od.product_id
                where od.order_id = $orderData[order_id];")
            );
            // wechat notify
//            Messager::sendTemplateMessage($config->messageTpl['order_exp_notify'], $orderData["wepay_openid"], array(
//                'first' => '您有一笔订单已发货',
//                'keyword1' => "#" . $orderData['serial_number'],
//                'keyword2' => $expressList[$expressCompany],
//                'keyword3' => $expressCode,
//                'remark' => '点击详情 随时查看订单状态'), 'http://' . $config->domain . "?/Order/expressDetail/order_id=$orderData[order_id]");
            // wechat notify test
            // assign
            $this->Smarty->assign('expcom', $expressList[$expressCompany]);
            $this->Smarty->assign('expcode', $expressCode);
            $this->Smarty->assign('toName', $userInfo->nickname);
            $this->Smarty->assign('fromName', $this->settings['shopname']);
            $this->Smarty->assign('fromAddress', $config->mail['account']);
            $this->Smarty->assign('order', $orderInfo);
            $content = $this->Smarty->fetch("email/user_express_email.html");
            $this->Email->send($userEmail, $this->settings['shopname'], (string) $subject, $content);
            echo 1;
        } else {
            echo 0;
        }
    }

    /*
     * @HttpPost only
     * 获取快递跟踪情况
     * @return <html>
     */

    public function ajaxGetExpressDetails() {
        $typeCom = $_POST["com"]; //快递公司
        $typeNu = $_POST["nu"];  //快递单号
        $url = "http://api.ickd.cn/?id=105049&secret=c246f9fa42e4b2c1783ef50699aa2c4d&com=$typeCom&nu=$typeNu&type=html&encode=utf8";
        //优先使用curl模式发送数据
        $res = Curl::get($url);
        echo $res;
    }

    /**
     * ajax 订单退款处理
     */
    public function orderRefund() {
        $this->loadModel('mOrder');
        $orderId = intval($this->pPost('id'));
        $ret = $this->mOrder->orderRefund($orderId);
        if ($ret !== false) {
            $suA = array(8, 9, 11);
            if (in_array($ret->refund_status, $suA)) {
                // 申请已提交 进一步处理订单
                $this->mOrder->updateOrderStatus($orderId, 'refunded');
                echo 1;
            } else {
                echo 0;
            }
        } else {
            echo 0;
        }
    }

}
